<?php

/**
 * 责任链模式：请求从一个到另一个handler,直到最终找到一个合适的处理器。
 * Class ChainOfResponsibility
 */

/**
 * 抽象类：账户Account. 定义pay()方法，下一个handler, 定义canPay()支付
 * 具体类：银行卡、信用卡、比特币类。每个类有一个余额属性，用来判断是否足够支付。
 */

// 抽象类：定义公共方法和对象。 下一个操作对象，操作行为。
abstract class Account
{
    protected $successor;
    protected $balance;

    public function setNext(Account $account)
    {
        $this->successor = $account;
    }

    public function pay(float $amountToPay)
    {
        if ($this->canPay($amountToPay)) {
            echo sprintf('付款 %s, 使用 %s', $amountToPay, get_called_class());
        } elseif ($this->successor) {
            echo sprintf('%s 余额不足以支付, 下一个...', get_called_class());
            $this->successor->pay($amountToPay);
        } else {
            throw new \Exception('所有账户余额都不足以支付');
        }
    }

    public function canPay($amount): bool
    {
        return $this->balance >= $amount;
    }
}

class Bank extends Account
{
    protected $balance;

    public function __construct(float $balance)
    {
        $this->balance = $balance;
    }
}

class Bitcoin extends Account
{
    protected $balance;

    public function __construct(float $balance)
    {
        $this->balance = $balance;
    }
}

class Paypal extends Account
{
    protected $balance;

    public function __construct(float $balance)
    {
        $this->balance = $balance;
    }
}

// usage
$bank = new Bank(100);
$paypal = new Paypal(200);
$bitcoin = new Bitcoin(300);

$bank->setNext($paypal);
$paypal->setNext($bitcoin);

$bank->pay(259);